//
//  UserAccount.swift
//  XMGWB
//
//  Created by 1 on 16/1/11.
//  Copyright © 2016年 xiaomage. All rights reserved.
//

import UIKit

// Swift2.0之后如果想自定义打印对象, 需要重写CustomStringConvertible协议中的description属性
// Swift2.0之前如果想自定义打印对象, 需要重写Printable协议中的description属性
class UserAccount: NSObject, NSCoding {
   
    /// 用户昵称
    var screen_name: String?
    
    /// 用户头像
    var avatar_large: String?

    /// 用于调用access_token，接口获取授权后的access token。
    var access_token: String?
 
    /// 保存真正的过期时间
    var expires_Date: NSDate?
    
    /// access_token的生命周期，单位是秒数。
    var expires_in: Int = 0
        //这一句什么时候执行
        {
        didSet
        {
            // 生成真正的过期时间
            expires_Date = NSDate(timeIntervalSinceNow: Double(expires_in))
        }
    }

     /// 当前授权用户的UID。
    var uid: String?
    
    init(dict: [String: AnyObject])
    {
        super.init()
        // 字典转模型
        // 如果现在构造方法中使用KVC必须先对当前对象进行初始化
        setValuesForKeysWithDictionary(dict)
        // 注意: 如果在构造方法中使用KVC赋值, 基本数据类型的属性必须有初始化值
    }
    
    // 利用KVC赋值时如果找不到对应的key就会调用
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {
        print("--字典转模型不成功调用--")
}
    // MARK:- 外部控制方法
     static let filePath = "userAccount.plist".cachesDir()
    
    /// 保存读取出来的授权模型
    static var account: UserAccount?
   
    /// 将当前对象写入文件中
    func saveUserAccount() -> Bool
    {
     
        // 2.归档对象---马上调用归档操作encodeWithCoder
        return NSKeyedArchiver.archiveRootObject(self, toFile: UserAccount.filePath)
    }
       /// 从文件中读取模型
    class func loadUserAccount() -> UserAccount?
    {
    // 1.判断是否已经加载过---开始一进来的时候UserAccount.account是 nil, 后来加载后才有的值
        if UserAccount.account != nil
        {
            //直接解档--- UserAccount.account
            return UserAccount.account!
        }

        // 2.1从文件中解归档对象
        let account = NSKeyedUnarchiver.unarchiveObjectWithFile(UserAccount.filePath) as? UserAccount
        
        // 2.2判断AccessToken是否过期
        // 当前时间 和 真正过期时间
        // 2016   2015
        if let date = account?.expires_Date where NSDate().compare(date) == NSComparisonResult.OrderedDescending
        {
            CBWLog("过期了")
            return nil
        }
        // 2.3没有过期
//        CBWLog(account?.avatar_large)
        return account

    }
    
    /// 返回当前用户是否登录--判断 plist 文件是否存在,存在即说明以前验证成功了
    class func isLogon() -> Bool {
        return UserAccount.loadUserAccount() != nil
    }
    /// 加载用户信息
    func loadUserInfo(finished: (dict: [String: AnyObject]?, error: NSError?)->())
    {
        
        // 断言: 用于程序员之间沟通
        // 断定access_token一定有值, 如果没有程序就会崩溃, 并且打印后面的message
        assert(access_token != nil, "必须有access_token才能使用该方法")
        assert(uid != nil, "必须有uid才能使用该方法")
//        CBWLog(access_token)
//        CBWLog(uid)
        // 1.准备路径
        let path = "2/users/show.json"
        // 2.准备参数
        let parameters = ["access_token": access_token!, "uid": uid!]
        // 3.发送Get请求
        NetworkTools.shareInstance.GET(path, parameters: parameters, success: { (task, objc) -> Void in
            
            // 3.1.对服务器返回的数据进行安全校验
            guard let dict = objc as? [String: AnyObject] else
            {
                CBWLog("服务器没有返回数据")
                return
            }
            
            // 3.2从获取到的用户信息中取出昵称和头像
            self.avatar_large = dict["avatar_large"] as? String
            self.screen_name = dict["screen_name"] as? String
            
            // 3.3保存授权信息
//                        self.saveUserAccount()
            finished(dict: dict, error: nil)
            
            }) { (task, error) -> Void in
                CBWLog(error)
                finished(dict: nil, error: error)
        }
    }
    // MARK:- NSCoding
    // 写入文件时调用
    func encodeWithCoder(aCoder: NSCoder)
    {
        aCoder.encodeObject(access_token, forKey: "access_token")
        aCoder.encodeObject(expires_in, forKey: "expires_in")
        aCoder.encodeObject(uid, forKey: "uid")
        aCoder.encodeObject(expires_Date, forKey: "expires_Date")
        //前往记得要写到文档中去
        aCoder.encodeObject(screen_name, forKey: "screen_name")
        aCoder.encodeObject(avatar_large, forKey: "avatar_large")
        
    }
    // 从文件中读取出来时调用
    // 系统给的类型和实际的类型不匹配
    required init?(coder aDecoder: NSCoder)
    {
        access_token = aDecoder.decodeObjectForKey("access_token") as? String
        expires_in = aDecoder.decodeObjectForKey("expires_in") as! Int
        uid = aDecoder.decodeObjectForKey("uid") as? String
        expires_Date = aDecoder.decodeObjectForKey("expires_Date") as? NSDate
        avatar_large = aDecoder.decodeObjectForKey("avatar_large") as? String
        screen_name = aDecoder.decodeObjectForKey("screen_name") as? String

    }
}
